package com.jzo2o.orders.manager.service.impl;

import com.jzo2o.api.trade.TradingApi;
import com.jzo2o.api.trade.dto.request.PayReqDTO;
import com.jzo2o.api.trade.dto.response.PayResDTO;
import com.jzo2o.api.trade.enums.PayChannelEnum;
import com.jzo2o.api.trade.enums.PayTypeEnum;
import com.jzo2o.common.expcetions.ForbiddenOperationException;
import com.jzo2o.mvc.utils.UserContext;
import com.jzo2o.orders.base.model.domain.Orders;
import com.jzo2o.orders.manager.Handler.OrdersHandler.*;
import com.jzo2o.orders.manager.model.dto.request.PlaceOrderReqDTO;
import com.jzo2o.orders.manager.model.dto.response.PlaceOrderResDTO;
import com.jzo2o.orders.manager.service.IOrdersManagerService;
import com.jzo2o.orders.manager.service.IPlaceOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Duration;

/**
 * \* User: chy
 * \* Date: 2025/9/30  11:30
 * \* Description: 处理用户下单相关接口
 * \
 */
@Service
@Slf4j
public class PlaceOrderServiceImpl implements IPlaceOrderService {

    private final OrderHandlerChain orderHandlerChain;
    private final RedisTemplate redisTemplate;
    private final TradingApi tradingApi;
    private final IOrdersManagerService ordersManagerService;

    public PlaceOrderServiceImpl(OrderHandlerChain orderHandlerChain, RedisTemplate redisTemplate , TradingApi tradingApi, IOrdersManagerService ordersManagerService) {
        this.orderHandlerChain = orderHandlerChain;
        this.redisTemplate = redisTemplate;
        this.tradingApi = tradingApi;
        this.ordersManagerService = ordersManagerService;
    }
    /**
     * 微信小程序用户下单
     *
     * @param reqDTO
     * @return
     */
    @Override
    public PlaceOrderResDTO placeOrders(PlaceOrderReqDTO reqDTO) {
//        // 1.创建每一步的操作对象
//        OrderCheckHandler checkHandler = new OrderCheckHandler();
//        OrderFillHandler fillHandler = new OrderFillHandler();
//        OrderCalculateHandler calculateHandler = new OrderCalculateHandler();
//        OrderSaveDbHandler saveDbHandler = new OrderSaveDbHandler();
//        OrderAfterHandler afterHandler = new OrderAfterHandler();
//        // 2.设置链路,按照顺序执行
//        checkHandler.setNext(fillHandler);
//        fillHandler.setNext(calculateHandler);
//        calculateHandler.setNext(saveDbHandler);
//        saveDbHandler.setNext(afterHandler);
//        // 3.开始处理
//        Orders orders = new Orders();
//        checkHandler.process(orders, reqDTO);
        log.info("开始处理用户下单请求");
        // 处理重复下单逻辑
        String key = "ORDER_CREAT" + UserContext.currentUserId() + reqDTO.getServeId();
        Boolean flag = redisTemplate.opsForValue().setIfAbsent(key, 1, Duration.ofSeconds(20));
        if (!flag) {
            log.warn("用户重复下单，请勿重复下单");
             throw new ForbiddenOperationException("用户重复下单，请勿重复下单");
        }

        Orders orders = new Orders();

        // 使用责任链处理订单
        orderHandlerChain.execute(orders, reqDTO);

        log.info("用户下单处理完成，订单ID: {}", orders.getId());
        return new PlaceOrderResDTO(orders.getId());
    }
    /**
     * 微信小程序用户下单支付
     *
     * @param OrderId
     * @param tradingChannel
     * @return
     */
    @Override
    public PayResDTO pay(Long OrderId, PayChannelEnum tradingChannel) {
        log.info("用户下单支付开始,订单ID:{},支付渠道:{}", OrderId, tradingChannel);
        PayReqDTO payReqDTO = new PayReqDTO();
        // 设置业务系统订单号
        payReqDTO.setProductOrderNo(OrderId);
        // 设置支付渠道
        payReqDTO.setTradingChannel(tradingChannel);
        // 设置支付类型
        payReqDTO.setPayType(PayTypeEnum.NATIVE);

        // 设置交易金额
        Orders orders = ordersManagerService.getById(OrderId);
        payReqDTO.setTradingAmount(orders.getRealPayAmount());
        // 设置memo
        payReqDTO.setMemo(orders.getServeItemName());
        PayResDTO payResDTO = tradingApi.toPay(payReqDTO);
        log.info("用户下单支付完成,订单ID:{},支付渠道:{}", OrderId, tradingChannel);
        // 保存支付单号
        orders.setTradingOrderNo(payResDTO.getPayOrderNo());
        ordersManagerService.updateById( orders);

        return payResDTO;
    }
}
